package org.railage.client.gui.dialogs;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.JLabel;

import org.apache.log4j.Logger;
import org.railage.client.Client;
import org.railage.client.gui.main.GUI;
import org.railage.common.dto.UserDTO;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.text.SimpleDateFormat;

import javax.swing.JSeparator;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.JComboBox;

import java.awt.Color;

public class TicketBuyDialog extends JDialog {

	public static final String SELECT_STATION_A = "-- Select departure --";
	public static final String SELECT_STATION_B = "-- Select destination --";
	public static final String UNKNOWN_TICKET_COUNT = "?";

	private static final long serialVersionUID = 724426235625855206L;

	private static final Logger log = Logger.getLogger(TicketBuyDialog.class);

	private final JPanel contentPanel = new JPanel();
	private JTextField surnameField;
	private JTextField nameField;
	private JTextField birthdayField;
	private JTextField tripField;
	private JTextField routeField;
	private JComboBox<String> depComboBox;
	private JComboBox<String> destComboBox;

	private SimpleDateFormat dateFormatter = new SimpleDateFormat(
			GUI.DATE_FORMAT);

	private String[] stations = null;

	private int tripID;
	private JTextField ticketsField;

	/**
	 * Create the dialog.
	 */
	public TicketBuyDialog(int tripID) {
		this.tripID = tripID;

		setTitle(GUI.PROGRAM_NAME + " - Buy ticket");
		setIconImage(Toolkit.getDefaultToolkit().getImage(
				getClass().getClassLoader().getResource(GUI.ICON_PATH)));
		setSize(463, 289);
		setResizable(false);
		setLocationRelativeTo(null);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(null);

		JLabel lblPleaseEnterYour = new JLabel(
				"Please select departure and destination points and press \"Buy\"");
		lblPleaseEnterYour.setBounds(10, 11, 394, 35);
		contentPanel.add(lblPleaseEnterYour);

		JSeparator separator_1 = new JSeparator();
		separator_1.setBounds(10, 44, 437, 2);
		contentPanel.add(separator_1);

		JLabel lblTrip = new JLabel("Trip ID");
		lblTrip.setBounds(10, 60, 55, 14);
		contentPanel.add(lblTrip);

		tripField = new JTextField();
		tripField.setEditable(false);
		tripField.setColumns(10);
		tripField.setBounds(65, 57, 49, 20);
		contentPanel.add(tripField);

		JLabel lblTickets = new JLabel("Tickets");
		lblTickets.setBounds(130, 60, 55, 14);
		contentPanel.add(lblTickets);

		ticketsField = new JTextField();
		ticketsField.setText(UNKNOWN_TICKET_COUNT);
		ticketsField.setForeground(Color.RED);
		ticketsField.setEditable(false);
		ticketsField.setColumns(10);
		ticketsField.setBounds(185, 57, 49, 20);
		contentPanel.add(ticketsField);

		JLabel lblRoute = new JLabel("Route");
		lblRoute.setBounds(10, 91, 55, 14);
		contentPanel.add(lblRoute);

		routeField = new JTextField();
		routeField.setEditable(false);
		routeField.setColumns(10);
		routeField.setBounds(65, 88, 169, 20);
		contentPanel.add(routeField);

		depComboBox = new JComboBox<String>();
		depComboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				fillDestinationCombobox(depComboBox.getSelectedIndex());
			}
		});
		depComboBox.setBounds(266, 57, 169, 20);
		contentPanel.add(depComboBox);

		destComboBox = new JComboBox<String>();
		destComboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setTicketsNumber();
			}
		});
		destComboBox.setBounds(266, 88, 169, 20);
		contentPanel.add(destComboBox);

		JSeparator separator_2 = new JSeparator();
		separator_2.setBounds(10, 119, 437, 2);
		contentPanel.add(separator_2);

		JTextPane info = new JTextPane();
		info.setBackground(UIManager.getColor("Panel.background"));
		info.setText("If you want to change your personal information please use File -> Personal info.");
		info.setBounds(20, 135, 130, 87);
		contentPanel.add(info);

		JLabel lblSurname = new JLabel("Surname");
		lblSurname.setBounds(225, 135, 82, 14);
		contentPanel.add(lblSurname);

		surnameField = new JTextField();
		surnameField.setEditable(false);
		surnameField.setBounds(317, 132, 118, 20);
		contentPanel.add(surnameField);
		surnameField.setColumns(10);

		JLabel lblName = new JLabel("Name");
		lblName.setBounds(225, 163, 82, 14);
		contentPanel.add(lblName);

		nameField = new JTextField();
		nameField.setEditable(false);
		nameField.setColumns(10);
		nameField.setBounds(317, 160, 118, 20);
		contentPanel.add(nameField);

		JLabel lblBirthday = new JLabel("Birthday");
		lblBirthday.setBounds(225, 191, 82, 14);
		contentPanel.add(lblBirthday);

		birthdayField = new JTextField();
		birthdayField.setEditable(false);
		birthdayField.setColumns(10);
		birthdayField.setBounds(317, 188, 118, 20);
		contentPanel.add(birthdayField);
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				JButton loginButton = new JButton("Buy");
				loginButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						buy();
					}
				});
				loginButton.setActionCommand("OK");
				buttonPane.add(loginButton);
				getRootPane().setDefaultButton(loginButton);
			}
			{
				JButton cancelButton = new JButton("Cancel");
				cancelButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						dispose();
					}
				});
				cancelButton.setActionCommand("Cancel");
				buttonPane.add(cancelButton);
			}
		}
	}

	public void init() {
		tripField.setText(String.valueOf(tripID));
		UserDTO user = Client.getInstance().getCurrentUser();
		surnameField.setText(user.getSurname());
		nameField.setText(user.getName());
		birthdayField.setText(dateFormatter.format(user.getBirthday()));

		String routeName = null;
		try {
			routeName = (String) Client.getInstance().callMethod(
					"getRouteByTripID", tripID);
			stations = (String[]) Client.getInstance().callMethod(
					"getOrderedStationsOfTrip", tripID);
		} catch (IOException e) {
			log.error(GUI.DISCON_UNEXP_LOG_MSG, e);
			JOptionPane.showMessageDialog(this, GUI.DISCON_UNEXP_GUI_MSG);
		}
		routeField.setText(routeName);
		fillDepartureCombobox();
		fillDestinationCombobox(0);

		// default close operation and visibility
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setVisible(true);
	}

	private void fillDepartureCombobox() {
		// all except last station
		String[] items = new String[stations.length];
		items[0] = SELECT_STATION_A;
		System.arraycopy(stations, 0, items, 1, stations.length - 1);

		depComboBox.setModel(new DefaultComboBoxModel<String>(items));
	}

	private void fillDestinationCombobox(int departureIndex) {
		String[] items = new String[] { SELECT_STATION_B };
		if (departureIndex != 0) {
			items = new String[stations.length - departureIndex + 1];
			items[0] = SELECT_STATION_B;
			System.arraycopy(stations, departureIndex, items, 1,
					stations.length - departureIndex);
		}
		ticketsField.setText(UNKNOWN_TICKET_COUNT);
		destComboBox.setModel(new DefaultComboBoxModel<String>(items));
	}

	private void setTicketsNumber() {
		if (depComboBox.getSelectedIndex() != 0
				&& destComboBox.getSelectedIndex() != 0) {
			int tickets;
			String[] request = new String[] { tripField.getText(),
					(String) depComboBox.getSelectedItem(),
					(String) destComboBox.getSelectedItem(), };
			try {
				tickets = (Integer) Client.getInstance().callMethod(
						"getAvailableTicketsNumber", request);
				ticketsField.setText(String.valueOf(tickets));
			} catch (IOException e) {
				log.error(GUI.DISCON_UNEXP_LOG_MSG, e);
				JOptionPane.showMessageDialog(this, GUI.DISCON_UNEXP_GUI_MSG);
			}
		} else {
			ticketsField.setText(UNKNOWN_TICKET_COUNT);
		}
	}

	private void buy() {
		if (depComboBox.getSelectedIndex() != 0
				&& destComboBox.getSelectedIndex() != 0) {
			String result = null;
			Object[] request = new Object[] {
					Client.getInstance().getCurrentUser().getId(), this.tripID,
					depComboBox.getSelectedItem(),
					destComboBox.getSelectedItem() };
			try {
				result = (String) Client.getInstance().callMethod("buyTicket",
						request);
				JOptionPane.showMessageDialog(this, result);
			} catch (IOException e) {
				log.error(GUI.DISCON_UNEXP_LOG_MSG, e);
				JOptionPane.showMessageDialog(this, GUI.DISCON_UNEXP_GUI_MSG);
			}
			dispose();
		} else {
			JOptionPane.showMessageDialog(this,
					"Departure and/or destination stations are not selected");
		}
	}
}
